package com.ruoyi.project.experiment.experimentstudent.controller;

import com.alibaba.fastjson.JSONObject;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.ilabUtils.IlabSport;
import com.ruoyi.common.utils.ilabUtils.IlabUtil;
import com.ruoyi.common.utils.ilabUtils.Key;
import com.ruoyi.common.utils.ilabUtils.Step;
import com.ruoyi.common.utils.uuid.UUID;
import com.ruoyi.framework.aspectj.lang.annotation.Log;
import com.ruoyi.framework.aspectj.lang.enums.BusinessType;
import com.ruoyi.framework.web.controller.BaseController;
import com.ruoyi.framework.web.domain.AjaxResult;
import com.ruoyi.framework.web.page.TableDataInfo;
import com.ruoyi.project.experiment.experimentstudent.domian.Result;
import com.ruoyi.project.experiment.experimentstudent.domian.StudentExperiment;
import com.ruoyi.project.experiment.experimentstudent.service.ITbExperimentReportService;
import com.ruoyi.project.experiment.onlineexperiment.domain.TbExperiment;
import com.ruoyi.project.experiment.onlineexperiment.service.ITbExperimentService;
import com.ruoyi.project.system.user.domain.User;
import com.ruoyi.project.util.token.JwtUtil;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.List;


/**
 * @ClassName StudentExperimentController
 * @Description TODO
 * @Author lvyongwei
 * @Date
 **/
@Controller
@RequestMapping("/system/report")
public class StudentExperimentController extends BaseController {

    private String prefix = "system/report";

    @Autowired
    private ITbExperimentService iTbExperimentService;

    @Autowired
    private ITbExperimentReportService iTbExperimentReportService;

    @Autowired
    private IlabUtil ilabUtil;

    private Logger logger = LoggerFactory.getLogger(StudentExperimentController.class);

    /**
     * 进入实验界面
     * @return
     */
    @RequiresPermissions("system:report:view")
    @GetMapping()
    public String report()
    {
        return prefix + "/report";
    }

    /**
     * 获取所有开放的实验
     * @return
     */
    @RequiresPermissions("system:report:list")
    @PostMapping("/list")
    @ResponseBody
    public TableDataInfo getAllOpenExperiment(TbExperiment tbExperiment){
        //System.out.println(tbExperiment);
        startPage();
        /**
         * 获取开放的实验
         */
        List<TbExperiment> tbExperimentList = iTbExperimentService.selectTbExperimentListOpen(tbExperiment);
        return getDataTable(tbExperimentList);
        /*
        try{
            List<TbExperiment> tbExperimentList = iTbExperimentService.selectTbExperimentListOpen(tbExperiment);
            return tbExperimentList;
        }catch (Exception e){
            return null;
        }*/
    }

    /**
     * 进入实验
     * @return
     */
    @RequiresPermissions("system:report:start")
    @GetMapping("/startExperiment")
    public String startExperiment(Long experimentId, ModelMap map){
        /**
         * 重复实验获取唯一标识区分
         */
        String uuid = UUID.randomUUID().toString();
        /**
         * 获取实验信息
         */
        TbExperiment tbExperiment = iTbExperimentService.selectTbExperimentById(experimentId);
        /**
         * 获取当前用户信息
         */
        User user = getSysUser();
        StudentExperiment studentExperiment=new StudentExperiment(experimentId,user.getUserId(),user.getUserName(),uuid,user.getAccessToken(),user.getLoginName());
        /**
         * 获取token
         */
        String token = JwtUtil.sign(studentExperiment,24*60*60*1000);
        /**
         * 实验信息网址拼接上token
         */
        tbExperiment.setExperimentHref(tbExperiment.getExperimentHref() + "?token=" + token);
        /**
         * 放入容器
         */
        map.put("tbExperiment",tbExperiment);
        map.put("uuid",uuid);
        return prefix+"/start";
    }


    /**
     * U3D提交实验结果
     */
    /**
     * 获取在线实验u3d传来的结果
     * @param result
     * @param request
     * @return
     */
    @PostMapping("/getExperimentResult")
    @ResponseBody
    @CrossOrigin
    @Log(title = "成绩提交",businessType = BusinessType.INSERT)
    public boolean getExperimentResult(@RequestBody Result result, HttpServletRequest request){
        String str="";
        /**
         * 获取用户和实验id
         * 如果参数keys中索引0不是“token” 或者values索引0为 即返回false
         */
        if(StringUtils.isEmpty(result.getValues()[0]) || result.getValues()[0]==null || !result.getKeys()[0].equals("token")){
            return false;
        }else{
            for(int i=1;i<result.getKeys().length;i++){
                str+=result.getKeys()[i]+":"+result.getValues()[i]+",";
            }
            str=str.substring(0,str.length()-1);
        }
        /**
         * 解析token
         */
        StudentExperiment studentExperiment = JwtUtil.unsign(result.getValues()[0],StudentExperiment.class);
        System.out.println(studentExperiment);
        /**
         * 判断是否有ilab唯一标识，是否上传ilab
         */
        if(!StringUtils.isEmpty(studentExperiment.getAccessToken())){
            /**
             * 结束时间
             */
            Long endTime = System.currentTimeMillis();
            /**
             * 实验开始时间
             */
            Long beginTime = studentExperiment.getReportDate();
            /**
             * 实验总分
             */
            int score = Integer.valueOf(result.getScore());
            IlabSport ilabSport = getIlabSport(beginTime, endTime, score, studentExperiment.getLoginName());
            ilabUtil.submitGrade(ilabSport, studentExperiment.getAccessToken());
        }
        studentExperiment.setReportDate(System.currentTimeMillis() - studentExperiment.getReportDate());
        studentExperiment.setU3dScore(Double.valueOf(result.getScore()));
        /**
         * 添加语句记得写
         */
        studentExperiment.setReportText(str);
        try{
            iTbExperimentReportService.insertTbExperimentReport(studentExperiment);
            return true;
        }catch (Exception e){
            e.printStackTrace();
            logger.error("在线实验成绩添加失败" + studentExperiment);
            return false;
        }
    }



    /**
     * 提交实验报告
     * @Param studentExperiment
     * @return
     */
    @RequiresPermissions("system:report:submit")
    @PostMapping("/submitReport")
    @ResponseBody
    public AjaxResult submitReport(@RequestBody StudentExperiment studentExperiment){
        studentExperiment.setReportStuId(getSysUser().getUserId());
        /**
         * 先进行判断是否提交过在线实验成绩
         */
        StudentExperiment studentExperiment1 = iTbExperimentReportService.getReport(studentExperiment);
        if(StringUtils.isNull(studentExperiment1) || studentExperiment1==null){
            return AjaxResult.error("请先进行在线实验操作");
        }
        /**
         * 进行提交实验报告操作
         */
        try{
            iTbExperimentReportService.updateTbExperimentReport(studentExperiment);
            return AjaxResult.success("提交成功");
        }catch (Exception e){
            return AjaxResult.error("提交失败");
        }
    }


    /**
     * 查看所有实验以及学生提交次数
     */
    @GetMapping("/look")
    public String check(ModelMap modelMap)
    {
        modelMap.addAttribute("reportStuId",getSysUser().getUserId());
        return prefix + "/result";
    }


    /**
     * 查询学生做此实验情况
     */
    @RequiresPermissions("system:report:list")
    @PostMapping("/list2")
    @ResponseBody
    public TableDataInfo result(StudentExperiment studentExperiment)
    {
        startPage();
        List<StudentExperiment> list =  iTbExperimentReportService.getResults2(studentExperiment);
        return getDataTable(list);
    }

    /**
     * 计算整合需要提交的成绩
     * @return
     */
    public IlabSport getIlabSport(Long startTime,Long endTime,Integer totalScore,String loginName){
        List<Step> steps = new ArrayList<>();
        /**
         * 计算开始时间和结束时间的差值
         */
        Long difference = endTime - startTime;
        /**
         * 时间间隔
         */
        Long interval = 38000L;
        int second = (int)(difference / 1000);
        Long startTime1 = startTime + 1000;
        Long endTime1 = startTime1 + (long)((difference - interval)/30);
        Long startTime2 = endTime1 + 2000;
        Long endTime2 = startTime2 + (long)((difference - interval)/20);
        Long startTime3 = endTime2 + 2000;
        Long endTime3 = startTime3 + (long)((difference - interval)/15);
        Long startTime4 = endTime3 + 2000;
        Long endTime4 = startTime4 + (long)((difference - interval)/15);
        Long startTime5 = endTime4 + 2000;
        Long endTime5 = startTime5 + (long)((difference - interval)/15);
        Long startTime6 = endTime5 + 2000;
        Long endTime6 = startTime6 + (long)((difference - interval)/30);
        Long startTime7 = endTime6 + 2000;
        Long endTime7 = startTime7 + (long)((difference - interval)/15);
        Long startTime8 = endTime7 + 2000;
        Long endTime8 = startTime8 + (long)((difference - interval)/30);
        Long startTime9 = endTime8 + 2000;
        Long endTime9 = startTime9 + (long)((difference - interval)/30);
        Long startTime10 = endTime9 + 2000;
        Long endTime10 = startTime10 + (long)((difference - interval)/20);
        Long startTime11 = endTime10 + 2000;
        Long endTime11 = startTime11 + (long)((difference - interval)/15);
        Long startTime12 = endTime11 + 2000;
        Long endTime12 = startTime12 + (long)((difference - interval)/30);
        Long startTime13 = endTime12 + 2000;
        Long endTime13 = startTime13 + (long)((difference - interval)/30);
        Long startTime14 = endTime13 + 2000;
        Long endTime14 = startTime14 + (long)((difference - interval)/20);
        Long startTime15 = endTime14 + 2000;
        Long endTime15 = startTime15 + (long)((difference - interval)/30);
        Long startTime16 = endTime15 + 2000;
        Long endTime16 = startTime16 + (long)((difference - interval)/30);
        Long startTime17 = endTime16 + 2000;
        Long endTime17 = startTime17 + (long)((difference - interval)/15);
        Long startTime18 = endTime17 + 2000;
        Long endTime18 = startTime18 + (long)((difference - interval)/20);
        Long startTime19 = endTime18 + 2000;
        Long endTime19 = startTime19 + (long)((difference - interval)/10);
        Step step1 = new Step(1,"步骤一",startTime1,endTime1,(int)((endTime1-startTime1)/1000),60,3,
                3, 1,"不错","还行","备注");
        Step step2 = new Step(2,"步骤二",startTime2,endTime2,(int)((endTime2-startTime2)/1000),90,2,
                2, 1,"不错","还行","备注");
        Step step3 = new Step(3,"步骤三",startTime3,endTime3,(int)((endTime3-startTime3)/1000),120,5,
                5, 1,"不错","还行","备注");
        Step step4 = new Step(4,"步骤四",startTime4,endTime4,(int)((endTime4-startTime4)/1000),120,5,
                5, 1,"不错","还行","备注");
        Step step5 = new Step(5,"步骤五",startTime5,endTime5,(int)((endTime5-startTime5)/1000),120,5,
                5, 1,"不错","还行","备注");
        Step step6 = new Step(6,"步骤六",startTime6,endTime6,(int)((endTime6-startTime6)/1000),60,3,
                3, 1,"不错","还行","备注");
        Step step7 = new Step(7,"步骤七",startTime7,endTime7,(int)((endTime7-startTime7)/1000),120,4,
                4, 1,"不错","还行","备注");
        Step step8 = new Step(8,"步骤八",startTime8,endTime8,(int)((endTime8-startTime8)/1000),60,2,
                2, 1,"不错","还行","备注");
        Step step9 = new Step(9,"步骤九",startTime9,endTime9,(int)((endTime9-startTime9)/1000),60,2,
                2, 1,"不错","还行","备注");
        Step step10 = new Step(10,"步骤十",startTime10,endTime10,(int)((endTime10-startTime10)/1000),90,4,
                4, 1,"不错","还行","备注");
        Step step11 = new Step(11,"步骤十一",startTime11,endTime11,(int)((endTime11-startTime11)/1000),150,5,
                5, 1,"不错","还行","备注");
        Step step12 = new Step(12,"步骤十二",startTime12,endTime12,(int)((endTime12-startTime12)/1000),60,1,
                1, 1,"不错","还行","备注");
        Step step13 = new Step(13,"步骤十三",startTime13,endTime13,(int)((endTime13-startTime13)/1000),60,3,
                3, 1,"不错","还行","备注");
        Step step14 = new Step(14,"步骤十四",startTime14,endTime14,(int)((endTime14-startTime14)/1000),90,4,
                4, 1,"不错","还行","备注");
        Step step15 = new Step(15,"步骤十五",startTime15,endTime15,(int)((endTime15-startTime15)/1000),60,2,
                2, 1,"不错","还行","备注");
        Step step16 = new Step(16,"步骤十六",startTime16,endTime16,(int)((endTime16-startTime16)/1000),60,3,
                3, 1,"不错","还行","备注");
        Step step17 = new Step(17,"步骤十七",startTime17,endTime17,(int)((endTime17-startTime17)/1000),120,4,
                4, 1,"不错","还行","备注");
        Step step18 = new Step(18,"步骤十八",startTime18,endTime18,(int)((endTime18-startTime18)/1000),90,3,
                3, 1,"不错","还行","备注");
        Step step19 = new Step(19,"步骤十九",startTime19,endTime19,(int)((endTime19-startTime19)/1000),180,40,
                totalScore - 60, 1,"不错","还行","备注");
        steps.add(step1);
        steps.add(step2);
        steps.add(step3);
        steps.add(step4);
        steps.add(step5);
        steps.add(step6);
        steps.add(step7);
        steps.add(step8);
        steps.add(step9);
        steps.add(step10);
        steps.add(step11);
        steps.add(step12);
        steps.add(step13);
        steps.add(step14);
        steps.add(step15);
        steps.add(step16);
        steps.add(step17);
        steps.add(step18);
        steps.add(step19);
        IlabSport ilabSport = new IlabSport(loginName, "光弹性应力分析虚拟实验", 1, totalScore,
                startTime,endTime,second, (int)Key.issuerId, java.util.UUID.randomUUID().toString().replaceAll("-","_"),steps);
        return ilabSport;
    }

    public static void main(String[] args) {
        StudentExperimentController studentExperimentController = new StudentExperimentController();
        IlabSport zhangdongsheng = studentExperimentController.getIlabSport(1624930122510L, 1624932051000L, 100, "zhangdongsheng");
        String jsonObject = JSONObject.toJSONString(zhangdongsheng);
        System.out.println(jsonObject);
    }
}
